#!/usr/bin/env python3

###
# Author: Samir Nasher Taher
# License: AGPLv3,  for the license text see LICENSE
# Description: This script creates the graphs from the csv and getTests.py
###


from getTests import getTests
from modules import CONFIG

import matplotlib.pyplot as plot
import numpy as np
import argparse, csv
from statistics import median, stdev

# csvs are built like this:
# <HOST>.csv
# and each row is one test, according to getTests.py

def getValues(filePath, idx):
    with open(filePath, 'r') as csvHandle:
        csvFile = csv.reader(csvHandle)
        x = 0
        for line in csvFile:
            if x == idx:
                return line
            else:
                x += 1

def getLabel(path):
    path = path.split('/')[-1] # get everything after the last /
    path = path.rsplit('.', 1) # split from right to first .
    return path[0]

def getUserPosNumber():
    """
    Gets a float or "" from an user.
    """
    number = "nan"
    while not (isinstance(number, float) or number == ""):
        try:
            number = input("Please enter a number, e.g. -3.2. Return for auto-setting.\t")
            if number != "":
                number = float(number)
        except ValueError:
            pass
    return number

def genGraph(test, idx):
    plot.title(test.getName())
    x_val = range(CONFIG.MEASUREMENTS)
    y_vals = [] # to save values for interactive y limit
    for filePath in filePaths: # loop through all files/hosts
        y_val = getValues(filePath, idx) # idx is the number of the test in getTests, which also is the line in which its values are
        y_vals.append(np.asfarray(np.array(y_val), float))
        plot.scatter(
                x_val, 
                y_vals[-1], 
                label=getLabel(filePath)
        )
        # add median for each scatter
        plot.plot(
                x_val,
                [median(y_vals[-1])]*len(x_val),
                label=getLabel(filePath)+" mean", 
                linestyle="--"
        )
    if args.interactive:
        axes = plot.gca()
        print(f"Set the y axis limit for {test.getName()}")
        print(f"Current (from,to): {axes.get_ylim()}")
        largest = 0
        for y_val in y_vals:
            if max(y_val) > largest:
                largest = max(y_val)
        print(f"Largest number is: {largest}")
        print("Medians are:")
        for y_val in y_vals:
            print(median(y_val))
        print("Standard deviations are:")
        for y_val in y_vals:
            print(round(stdev(y_val), 4))

        print("Setting lower limit of the y-axis")
        y_limit_min = getUserPosNumber()
        if y_limit_min == "":
            y_limit_min = axes.get_ylim()[0]
        print("Setting upper limit of the y-axis")
        y_limit_max = getUserPosNumber()
        if y_limit_max == "":
                y_limit_max = axes.get_ylim()[1]

        newLimit = [y_limit_min, y_limit_max]
        if not (newLimit == axes.get_ylim()):
            axes.set_ylim([y_limit_min, y_limit_max])

    plot.xlabel("Measurements")
    plot.ylabel("Reponse time in ms")
    plot.grid(axis='y')
    plot.legend()
    plot.show()




if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Create the CSVs.')
    parser.add_argument('files', nargs='+', help='Files to create the CSVs from.')
    parser.add_argument("-i", "--interactive", help="ask to tet the limit of the y-axis", action="store_true")
    args = parser.parse_args()
    filePaths = args.files

    # only to get metadata
    tests = getTests("")

    for idx, test in enumerate(tests):
        genGraph(test, idx)

